package com.jswdwsx.common.utils;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Component
@Slf4j
public class JsonUtils {

    //设置null值不参与序列化(字段不被显示)
    //this.setSerializationInclusion(JsonInclude.Include.NON_NULL);

    // 禁用空对象转换json校验
    //this.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
    //this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    //驼峰命名法转换为小写加下划线
    //this.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);

    private static ObjectMapper tbObjectMapper = new Jackson2ObjectMapperBuilder()
            .failOnEmptyBeans(false)
            .failOnUnknownProperties(false)
            .build();

    public static <T> Optional<T> jsonToObjectOptional(String json, Class<T> clazz) {
        try {
            return Optional.of(tbObjectMapper.readValue(json, clazz));
        } catch (IOException e) {
            log.error("字符串转java对象失败，{}", e.getMessage());
        }
        return Optional.empty();
    }

    public static <T> T jsonToObject(String json, Class<T> clazz) {
        try {
            return tbObjectMapper.readValue(json, clazz);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static <T> List<T> jsonToList(String json, Class<T> clazz) {
        JavaType javaType = tbObjectMapper.getTypeFactory().constructParametricType(List.class, clazz);
        try {
            return tbObjectMapper.readValue(json, javaType);
        } catch (IOException e) {
            log.error("字符串转List失败，{}", e.getMessage());
        }
        return Collections.emptyList();
    }

    public static <T, V> Map<T, V> jsonToMap(String json, Class<T> tClazz, Class<V> vClazz) {
        JavaType javaType = tbObjectMapper.getTypeFactory().constructParametricType(Map.class, tClazz, vClazz);
        try {
            return tbObjectMapper.readValue(json, javaType);
        } catch (IOException e) {
            log.error("字符串转Map失败，{}", e.getMessage());
        }
        return Collections.emptyMap();
    }

    public static String toJson(Object o) {
        try {
            return tbObjectMapper.writeValueAsString(o);
        } catch (IOException e) {
            log.error("字符串转List失败，{}", e.getMessage());
        }
        return "";
    }

}
